﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AAA.ResultSet
{
    public abstract class AbstractResultSet : IResultSet
    {
        private List<string> _lstColumnName;
        private List<string> _lstColumnHeader;
        private int _iCurrentIndex;
        private Dictionary<string, List<object>> _dicResultSet;
        private Dictionary<string, string> _dicAttribute;
        private bool _isSuccess;
        private string _strErrorMessage;
        private bool _isDoEvents;
        private Encoding _encoding;

        public Encoding Encoding
        {
            get { return _encoding; }
            set { _encoding = value; }
        }

        public bool IsDoEvents
        {
            get { return _isDoEvents; }
            set { _isDoEvents = value; }
        }

        public AbstractResultSet()
        {
            Clear();
        }

        protected void Clear()
        {
            _lstColumnName = new List<string>();
            _lstColumnHeader = new List<string>();
            _iCurrentIndex = -1;
            _dicResultSet = new Dictionary<string, List<object>>();
            _dicAttribute = new Dictionary<string, string>();
        }

        protected void AddColumn(string strColumnName)
        {
            AddColumn(strColumnName, strColumnName);
        }

        protected void AddColumn(string strColumnName, string strColumnHeader)
        {
            if (_lstColumnName.IndexOf(strColumnName) > -1)
                return;

            _lstColumnName.Add(strColumnName);
            _lstColumnHeader.Add(strColumnHeader);
            _dicResultSet.Add(strColumnName, new List<object>());
        }

        protected void AddRow(object[] oValues)
        {
            if (oValues.Length != _lstColumnName.Count)
                return;
            

            for (int i = 0; i < _lstColumnName.Count; i++)
                _dicResultSet[_lstColumnName[i]].Add(oValues[i]);
        }

        #region IResultSet Members

        public void Close()
        {
            Clear();
        }

        public abstract bool Load();

        public void SetAttribute(string strAttribute, string strValue)
        {
            if (_dicAttribute.ContainsKey(strAttribute))
                _dicAttribute[strAttribute] = strValue;
            else
                _dicAttribute.Add(strAttribute, strValue);
        }

        public string GetAttribute(string strAttribute)
        {
            return _dicAttribute.ContainsKey(strAttribute)
                    ? _dicAttribute[strAttribute]
                    : null;
        }

        public bool IsSuccess
        {
            get { return _isSuccess; }
            set { _isSuccess = value; }
        }

        public string ErrorMessage
        {
            get { return _strErrorMessage; }
            set { _strErrorMessage = value; }
        }

        public void Reset()
        {
            _iCurrentIndex = -1;
        }

        public bool Read()
        {
            return _lstColumnName.Count > 0 ? ++_iCurrentIndex < _dicResultSet[_lstColumnName[0]].Count : false;
        }

        public int RowCount
        {
            get { return _lstColumnName.Count > 0 ? _dicResultSet[_lstColumnName[0]].Count : 0; }
        }

        public int ColumnCount
        {
            get { return _lstColumnName.Count; }
        }

        public object Cells(int iIndex)
        {
            try
            {
                return Cells(_lstColumnName[iIndex]);
            }
            catch (Exception ex)
            {
                ErrorMessage = ex.Message + "," + ex.StackTrace;
                IsSuccess = false;
            }
            return null;
        }

        public object Cells(string strColumnName)
        {
            try
            {
                return _dicResultSet[strColumnName][_iCurrentIndex];
            }
            catch (Exception ex)
            {
                ErrorMessage = ex.Message + "," + ex.StackTrace;
                IsSuccess = false;
            }
            return null;
        }

        public List<object> GetColumn(int iIndex)
        {
            return GetColumn(_lstColumnName[iIndex]);
        }

        public List<object> GetColumn(string strColumnName)
        {
            return _dicResultSet[strColumnName];
        }

        public List<string> ColumnNames()
        {
            return _lstColumnName;
        }

        public List<string> ColumnHeaders()
        {
            return _lstColumnHeader;
        }

        #endregion
    }
}
